package p.ithorns.framework.api;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;

/**
 * VersionComparator
 *
 * @author Ht.L
 * @date 2024-03-08 15:19
 * @since 1.0.0
 */
public class VersionComparator implements Comparator<String> {

    public static void main(String[] args) {
        VersionComparator comparator = new VersionComparator();
        List<String> versions = Arrays.asList(
                "1.0.2",
                "1.0.0-beta.2",
                "1.0.0",
                "1.0.0-beta",
                "1.0.0-alpha.12",
                "1.0.0-beta.11",
                "1.0.1",
                "1.0.11",
                "1.0.0-rc.1",
                "1.0.0-alpha.1",
                "1.1.0",
                "1.0.0-alpha.beta",
                "1.11.0",
                "1.0.0-alpha.12.ab-c",
                "0.0.1",
                "1.2.1",
                "1.0.0-alpha",
                "1.0.0.1",  // Also works with a number of sections different than 3
                "1.0.0.2",
                "2",
                "10",
                "1.0.0.10"
        );
        versions.stream()
                .sorted(comparator::compare)
                .forEach(System.out::println);

    }

    @Override
    public int compare(final String o1, final String o2) {
        if (isEmpty(o1) || isEmpty(o2)) {
            throw new IllegalArgumentException("One or all parameters are null.");
        }

        String v1 = o1.replace("_", ".").replace("-", ".").replaceAll("[^\\d.]+", "0");
        String v2 = o2.replace("_", ".").replace("-", ".").replaceAll("[^\\d.]+", "0");

        v1 = v1.toLowerCase(Locale.ROOT);
        v2 = v2.toLowerCase(Locale.ROOT);

        String[] s1 = v1.split("\\.");
        String[] s2 = v2.split("\\.");
        int len1 = s1.length;
        int len2 = s2.length;
        int i, j;
        for (i = 0, j = 0; i < len1 && j < len2; i++, j++) {
            int big = 1;
            int small = -1;

            if (i == 0 && j == 0) {
                //大版本不一致
                big = 2;
                small = -2;
            }

            if (Long.parseLong(s1[i]) > Long.parseLong(s2[j])) {
                return big;
            } else if (Long.parseLong(s1[i]) < Long.parseLong(s2[j])) {
                return small;
            }
        }
        while (i < len1) {
            if (Long.parseLong(s1[i]) != 0) {
                return 1;
            }
            i++;
        }
        while (j < len2) {
            if (Long.parseLong(s2[j]) != 0) {
                return -1;
            }
            j++;
        }
        return 0;
    }

    private boolean isEmpty(String str) {
        return null == str || str.length() == 0;
    }
}